Copyright □ 1999, by Professor Jong-Hwan Kim, Korea Advanced Institute of Science and Technology (KAIST).  All rights reserved. Reproduction or translation of any part of this work is unlawful. Request for permission or further information should be addressed to Professor Jong-Hwan Kim at <johkim@vivaldi.kaist.ac.kr> or <Tel: +82-42-869-3448>.

Prof. Jong-Hwan Kim	Intelligent Control Lab, KAIST

10.로봇 제어 프로그램 Ⅳ

로봇이 공을 차는 행위를 프로그램화한 것이 Kick 함수이다. Kick 함수에서 로봇이 상대편 골대를 향하여 공을 차면 슛이 될 것이고, 로봇이 자기편 로봇쪽으로 공을 차주면 패스가 될것이고, 골키퍼가 골영역에 공을 놓고 차면 골킥이 될 것이다. 여기서는 로봇이 상대편 골대로 공을 차게 하는 Kick 함수에 대해서 살펴보자. 로봇 축구가 더 발전하면 공을 자기 진영의 자기편 로봇에게 백패스도 가능하겠지만, 여기서는 상대편 진영으로 공을 차는 것을 주로 고려하였다.

10.1 Kick 함수 - 상태 다이어그램법

로봇이 상대편 골대로 공을 차게 하는 Kick 함수는 여러 가지 방법으로 구현할 수 있다. 여기서 다루는 부분은 그 중에서도 일부분에 해당한다. 지금까지 배운 로봇을 움직이게 하는 함수는 Posture와 Shoot 이다. Posture만을 사용하여 Kick 함수를 구현할 수 있고, Posture함수와 Shoot 함수를 같이 사용하여도 가능하다. 이런 두 가지 방법을 위해 먼저 상태다이어그램에서 상태(state)와 천이(transition)에 대하여 알아본다.

그림 10. 상태다이어그램

그림 10.1은 로봇축구에서 사용될 수 있는 기본적인 상태다이어그램들의 상태와 천이에 대한 것을 보여준다. 그림 10.1(a)는 두 가지 상태가 존재하고, 이들이 천이함수 1과 2에 의해서 상태1과 상태 2로 바뀐다. 즉, 처음 상태가 1이면 천이함수 2에 의해서 상태 2가 되고 다시 상태 2에서 천이 함수 1에 의해 상태 1이 된다. 이를 적용한 예가 그림 10.2와 같다.

(a) 로봇이 공보다 뒤에 있을 때	(b) 로봇이 공보다 앞에 있을 때

그림 10. 로봇과 공의 두 가지 상태

그림 10.2 (a)의 상태를 상태 1로 생각할 수 있다. 즉, 로봇의 x 좌표값이 공의 x 좌표값보다 작을 때이다. 그림 10.2(b)는 상태 2로 여길 수 있고 로봇의 x 좌표값이 공의 x 좌표값보다 클 때이다. 그림 10.2 (a)에서 로봇이 공을 차지 못했을 경우 로봇이 공을 지나치므로 로봇의 x 좌표값이 공의 x 좌표값보다 커진다. 이 때는 그림 10.2(b)와 같은 경우이다. 이 경우에는 로봇이 공을 차기 위해서 그림 10.2(b)와 같은 경로로 움직여야 한다. 그림 10.2의 상태와 천이함수를 다음과 같이 정리할 수 있다.

- 상태 1: [eqn: rm Robot_x < Ball_x] 일 때 로봇이 공을 차는 상태

- 상태 2: [eqn: rm Robot_x > Ball_x] 일 때 로봇이 공을 차는 상태

- 천이함수 1: [eqn: rm Robot_x < Ball_x] 인 경우 상태 1로

- 천이함수 2: [eqn: rm Robot_x > Ball_x] 인 경우 상태 2로

여기서 [eqn: rm Robot_x]와 [eqn: rm Ball_x]는 각각 로봇과 공의 x 좌표값이다.

로봇이 공을 차는 상황을 그림 10.2와 같이 두 상태만을 사용하여 간단히 나타낼 수 있으나, 좀 더 정밀하게 나타내기 위하여 그림 10.1(b)와 (c)는 상태가 세 가지 경우로 나타낼 수 있다. 그림 10.1(b)의 경우는 각 상태에서 다른 상태로 이동하는 천이함수들이 존재한다. 그러나 그림 10.1(c)의 경우는 상태 2에서 상태 1로 이동하는 천이함수가 존재하지 않는다. 이와 같은 경우가 그림 10.3에 해당한다. 상태 1은 로봇의 x 좌표값이 공의 x 좌표값보다 작은 경우로 로봇이 공 뒤에 놓여 있어 상대편 골대로 슛을 하기 좋은 상태이고, 상태 2는 로봇이 공 바로 앞에 있는 경우이며, 상태 3은 로봇이 공 앞에 약간 떨어져 있는 경우이다. 상태 2에서 로봇이 공의 뒤쪽으로 이동하려다가, 즉 상태 2에서 상태 1로 이동하려다가 공을 자기 진영 쪽으로 차는 경우가 생기기 쉬우므로 먼저 공 앞쪽으로 더 이동한 후(상태 3) 공을 차기 좋은 위치(상태 1)로 이동하여 상대방 진영으로 공을 찬다. 이런 경우는 Posture 함수만을 사용하여 Kick 함수를 구현할 수 있다.

그림 10. 세 가지 상태의 경우

다음의 프로그램은 그림 10.1(a)의 경우를 구현한 것으로 Posture 함수와 Shoot 함수를 이용했다. 즉, 로봇이 공보다 앞쪽에 위치할 경우에는 Posture 함수를 이용하여 공 옆쪽으로 이동한 후 Shoot 함수를 이용하여 공을 상대방 골대 쪽으로 찬다. 아래의 Kick 함수에서 nKick = 0인 경우가 case 0로 상태 1에 해당하며 이 경우가 그림 10.2(a)이고, nKick = 1인 경우가 case 1로 상태 2에 해당하며 그림 10.2(b)의 경우이다. 그리고 이 프로그램에 사용된 수치의 단위는 cm로 (150, 65)는 경기장의 x 좌표값이 150cm, y 좌표값이 65cm로 상대편 골대 중앙부분을 의미한다.

void Kick(int whichrobot)

{

switch(nKick){

case 0:	// 상태 1의 경우 Shoot으로 공을 골대로 찬다.

Shoot(whichrobot, PositionOfBall[0], PositionOfBall[1], 150, 65);

if(PositionOfBall[0] < PositionOfHomeRobot[whichrobot][0])

// [eqn: rm Robot_x > Ball_x] 인 경우에 상태 2로 이동

nKick = 1;

break;

case 1:	// 상태 2의 경우 Posture으로 공 옆쪽으로 이동한다.

if(PositionOfBall[1]>PositionOfHomeRobot[whichrobot][1])

Posture(whichrobot, PositionOfBall[0]-3.0, PositionOfBall[1]-10.0);

else

Posture(whichrobot, PositionOfBall[0]-3.0, PositionOfBall[1]+10.0);

if( PositionOfBall[0] > PositionOfHomeRobot[whichrobot][0]-3.0)

// [eqn: rm Ball_x > (Robot_x - 3.0)]cm 인 경우에 상태 1로 이동

nKick = 0;

break;

}

}

위에서 보인 예제 프로그램에서는 로봇이 공 바로 앞에 있을 경우 상태 1로 되돌아가려다가 공을 자기편 진영으로 차는 경우가 발생한다. 그리고 공이 경기장 벽 근처에 있는 경우 ([eqn: rm (130cm - Ball_y )<5cm] 또는 [eqn: rm (Ball_y )<5cm], 여기서 [eqn: rm Ball_y]는 공의 y 좌표값이다. )에 로봇이 공을 상대편 골대 쪽으로 차지 못한다. Kick 함수는 이러한 경우도 고려하여 프로그램 되어야 한다. 그리고 Shoot 함수는 원의 궤적을 따라서 공을 차는 함수로 공 근처에서 큰 원의 궤적을 그리면서 차는 단점도 있다. 이렇게 되면 공까지 도달하는데 시간이 더 걸리므로 상대편 로봇에게 공을 빼앗길 수 있다. 이 문제는 공의 바로 근처의 새로운 상태를 생각하여 넣어주면 해결할 수 있다.

10.2 Kick 함수 - 단위 벡터장법

Kick 함수의 또 다른 구현 방법으로는 단위 벡터장(Uni-vector field method)법을 이용할 수 있다. 단위벡터란 크기가 1인 각도 정보만을 가지는 벡터를 뜻한다. 이러한 단위벡터로 구성되 장(field)을 단위벡터장이라고 한다. 즉, 단위벡터장 내의 모든 벡터는 크기가 1이고 각도 값만을 작는 단위벡터이다. 이절에서는 단위 벡터장법으로 로봇을 원하는 위치에 원하는 각도로 이동하하는 방법을 알아본다.

그림 10. 단위 벡터장

그림 10.4는 크기가 1이고 각도값을 갖는 단위벡터로 구성된 단위 벡터장을 나타낸다. 여기서 작은원과 선분은 로봇의 현재위치와 그때의 로봇의 방향각을 나타낸다. p는 현재 로봇의 위치이고, g는 공의 위치이고 r은 공 앞에 설정된 임의의 지점이다. 위치 p =[eqn: (x, y)~]에서 단위 벡터를 [eqn: F(x, y)] 또는 [eqn: F(p)~]라고 하자. 그러면 로봇의 위치 p에서 생성된 벡터는 다음과 같다:

[eqn: & |F(p)| ~~= ~1# & ANGLE F(p)~=~ANGLE VEC{pg}~-~n phi]

(10.1)

여기서 [eqn: phi =ANGLE vec{pr}-angle vec{pg}]이고, [eqn: n~]은 적절히 선정된 양의 상수이다. 그림 10.4에서 작은 원들은 로봇들의 현재위치이고 선분은 그 위치에서 로봇이 향해가야 하는 방향각을 나타낸다. 이러한 단위 벽터들을 경기장 내의 모든 지점에서 식 (10.1)에서 구할 수 있어 단위 벡터장을 형성한다. 옅은 실선으로 나타낸 부분은 임의의 여러점(로봇의 초기위치)에서 벡터장의 흐름으로 큰 원의 궤적을 나타내는 것을 알 수 있다. 로봇은 결국 이 궤적을 따라 이동하도록 제어될 것이다. 단위 벡터장의 모양과 로봇의 회전 움직임은 계수 [eqn: n~]과 선분[eqn: bar {gr}]의 길이에 따라 달라진다. 그림 10.4에서 로봇의 목표 위치는 공의 위치인 g 점이고, r은 로봇의 최종 방향각이 상대편 진영인 오른쪽으로 향하게 하는 벡터장을 구하기 위한 점이다. 실제 적용에 있어서는 최종목표점을 g 대신 r로 선정하여 로봇이 좀더 강하게 공을 찰 수 있게 할 수 있다.

다음은 실제로 이 단위 벡터장에서 구한 궤적을 따라 가게끔 제어를 하여야 한다. 이를 위하여 다음의 방법으로 로봇의 방향각과 벡터장으로부터 구한 궤적의 각오차를 줄일 수 있다:

[eqn: omega &=&K_p ~theta_e &+&K_d~dot{theta_e} # theta_e &=&ANGLE ~F(p)&-&theta_c # dot{theta_e} &=& {d{theta_e}}over{dt}]

(10.2)

여기서 [eqn: omega]는 각속도이고, [eqn: theta_e]는 로봇의 방향각([eqn: theta_c])과 벡터장 방향각[eqn: (angleF(p)}{})]과의 각도오차이고, [eqn: K_p, ~K_d]는 비례 궤환 계수와 시간 미분 궤환 계수이다. 식(10.2)와 로봇의 모델링 식을 이용하여 실제 로봇 제어의 입력인 오른쪽 바퀴와 왼쪽 바퀴의 속도를 구하면 다음과 같다:

[eqn: V_R ~=~V_c~ + {D}over{2}(~K_p ~theta_e ~+ ~K_d~dot{theta_e}&)# V_L ~=~V_c~ - {D}over{2}(~K_p ~theta_e ~+ ~K_d~dot{theta_e}&)]

(10.3)

위 식에서 [eqn: V_c] = 0 이면 로봇의 방향각은 벡터장의 방향각으로 향하게 된다.

단위 벡터장법을 이용해서 로봇을 제어할 때의 문제점으로는, 그림 10.4에서 알 수 있듯이 로봇이 벡터장을 따라서 목표점(g 점)으로 이동할 때에 이 근처에서 진동하는 특성이 나온다. 이는 목표점 근처에서 벡터장이 갑자기 변하기 때문이다. 즉, 목표점 왼쪽 영역의 위 부분은 벡터장이 아래쪽을 향하고 있고, 아래 부분은 위쪽을 향하고 있다. 그리고 목표점과 같은 선상에서는 벡터장이 직선으로 오른쪽을 향하고 있다. 이 부분에서 로봇이 조금만 벗어나면 벡터장의 방향이 위아래로 급격히 바뀌므로 로봇을 일직선으로 곧바로 가게 하는 제어를 하기가 어렵다. 이를 해결하기 위하여 목표점 근처에 확장 영역을 도입할 수 있다.

그림 10.4에서 알 수 있듯이 목표점을 잇는 수평선 중심 영역의 벡터장 흐름이 좁다. 이 영역근처에서 벡터장의 방향은 부드럽게 변하지 않는다. 그래서 이 좁은 영역으로 로봇이 이동하게 되면 로봇은 좌우로 비틀거리는 움직임을 보인다. 이를 보완하기 위해서 좁은 영역을 늘린 확장 영역을 고려하였다. 확장 영역의 폭은 로봇의 폭과 같게 설정한다. 이 늘어난 영역의 위아래 부분에서의 벡터장은 앞에서 언급한 단위 벡터장법으로 구한다. 이 때 목표점은 공의 좌표값과는 다르게 설정한다. 즉, 로봇이 윗부분에 있을 경우 앞에서 잡았던 g와 r 점대신에 그림 10.5에서 보듯이 이 확장 영역 위 부분에서 이 두 점 설정하여 벡터장을 계산한다. 즉, 로봇이 윗부분에 있을 경우 확장 영역에서의 g와 r 점은 공보다 위쪽 위치로 설정한다. 그리고 공의 아래쪽 영역에서는 위에서 구한 벡터장을 대칭으로 하여 구한다. 즉, 공의 윗 영역에서 구한 각에다 부(-)의 부호를 붙이면 공 아래쪽 영역에서의 벡터장을 구할 수 있다. 이와 같이 하면 로봇은 단위 벡터장을 따라가다가 확장영역으로 들어가게 된다. 이 확장영역에서는 목표점을 실제의 공의 좌표값으로 한다. 결국 이 영역이 존재함으로써 단위 벡터장이 부드럽게 변하므로 로봇이 목표점으로 접근 할 때에 흔들림 현상이 사라지게 된다. 확장영역에서의 벡터장의 방향각은 공으로 향하도록 설정했다. 이를 이용한 프로그램 코드는 생략한다.

그림 10. 개선된 단위 벡터장

위에서 말한 단위 벡터장 이외에도 Kick 함수는 여러 가지 많은 방법으로 구현될 수 있다. 최근에 많이 사용하는 방법은 그림 10.6에서와 같이 원과 직선을 이용한 것이다.

즉, 로봇의 위치와 공의 위치에 내접하는 원을 구한 후 이를 직선과 호로 연결했을 때 가장 짧은 거리의 경로를 찾는다. 그림 10.6에서 [eqn: theta_h]는 초기 위치에서의 로봇의 방향각이고, [eqn: theta_d]는 최종점에서의 로봇이 향해야 하는 방향각이다. 이런 방법을 적용하기 위해서는 먼저 로봇이 거쳐야할 경로를 만들어낸다. 그리고 나서 로봇이 향해야 할 각과 매 순간 로봇의 방향각과의 오차를 이용하여 식 (10.3)으로부터 같은 로봇의 오른쪽과 왼쪽의 바퀴 제어 속도입력을 만들 수 있다. 로봇축구에 있어서 로봇이 공을 상대방 골대로 최단 시간 내에 정확하게 차게 하는 Kick 함수가 대단히 중요하므로 이에 대한 연구는 계속되어야 할 것이다.

그림 10. 원과 직선의 방법